package com.linkstec.quartz.source;

import java.util.Map;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;

import lombok.extern.slf4j.Slf4j;

/**
 * Quartz调度管理器
 *
 * @author Administrator
 *
 */
@Slf4j
public class QuartzManager {
    private static String JOB_GROUP_NAME = "PUSH_JOBGROUP_NAME";
    private static String TRIGGER_GROUP_NAME = "PUSH_TRIGGERGROUP_NAME";

    /**
     * @Description: 添加一个定时任务，使用默认的任务组名，触发器名，触发器组名
     *
     * @param sched
     *            调度器
     *
     * @param jobName
     *            任务名
     * @param cls
     *            任务
     * @param time
     *            时间设置，参考quartz说明文档
     *
     * @Title: QuartzManager.java
     */
    public static void addJob(Scheduler sched, String jobName, @SuppressWarnings("rawtypes") Class cls, String time, Map<String, Object> map) {
        try {
            JobKey jobKey = new JobKey(jobName);
            @SuppressWarnings("unchecked")
            JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobKey).build();
            jobDetail.getJobDataMap().putAll(map);
            // 触发器
            Trigger trigger = TriggerBuilder
            .newTrigger()
            .withIdentity(jobName, TRIGGER_GROUP_NAME)
            .withSchedule(
                CronScheduleBuilder.cronSchedule(time))
            .build();

            sched.scheduleJob(jobDetail, trigger);
            // 启动
            if (!sched.isShutdown()) {
                sched.start();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: 添加一个定时任务
     *
     * @param sched
     *            调度器
     *
     * @param jobName
     *            任务名
     * @param jobGroupName
     *            任务组名
     * @param triggerName
     *            触发器名
     * @param triggerGroupName
     *            触发器组名
     * @param jobClass
     *            任务
     * @param time
     *            时间设置，参考quartz说明文档
     *
     * @Title: QuartzManager.java
     */
    public static void addJob(Scheduler sched, String jobName, String jobGroupName, String triggerName, String triggerGroupName, @SuppressWarnings("rawtypes") Class jobClass, String time) {
        try {
            JobKey jobKey = new JobKey(jobName);
            @SuppressWarnings("unchecked")
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobKey).build();
            // 触发器
            Trigger trigger = TriggerBuilder
                    .newTrigger()
                    .withIdentity(triggerName, triggerGroupName)
                    .withSchedule(
                        CronScheduleBuilder.cronSchedule(time))
                    .build();
            sched.scheduleJob(jobDetail, trigger);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: 修改一个任务的触发时间(使用默认的任务组名，触发器名，触发器组名)
     *
     * @param sched
     *            调度器
     * @param jobName
     * @param time
     *
     * @Title: QuartzManager.java
     */
    @SuppressWarnings("rawtypes")
    public static void modifyJobTime(Scheduler sched, String jobName, String time, Map<String, Object> map) {
        try {
            TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_GROUP_NAME);
            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
            if (trigger == null) {
                return;
            }
            String oldTime = trigger.getCronExpression();
            JobKey jobKey = new JobKey(jobName, JOB_GROUP_NAME);
            JobDetail jobDetail = sched.getJobDetail(jobKey);
            jobDetail.getJobDataMap().putAll(map);
            if (!oldTime.equalsIgnoreCase(time)) {
                Class objJobClass = jobDetail.getJobClass();
                removeJob(sched, jobName);
                addJob(sched, jobName, objJobClass, time, map);
                log.info(jobName + "调度变更前：" + oldTime + "调度变更后：" + time);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: 修改一个任务的触发时间
     *
     * @param sched
     *            调度器 *
     * @param sched
     *            调度器
     * @param triggerName
     * @param triggerGroupName
     * @param time
     *
     * @Title: QuartzManager.java
     */
    public static void modifyJobTime(Scheduler sched, String triggerName, String triggerGroupName, String time) {
        try {
            TriggerKey triggerKey = new TriggerKey(triggerName, triggerGroupName);
            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
            if (trigger == null) {
                return;
            }
            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(time)) {
                Trigger newTrigger = TriggerBuilder
                        .newTrigger()
                        .withIdentity(triggerName, triggerGroupName)
                        .withSchedule(
                            CronScheduleBuilder.cronSchedule(time))
                        .build();
                // 重启触发器
                sched.rescheduleJob(triggerKey, newTrigger);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: 移除一个任务(使用默认的任务组名，触发器名，触发器组名)
     *
     * @param sched
     *            调度器
     * @param jobName
     *
     * @Title: QuartzManager.java
     */
    public static void removeJob(Scheduler sched, String jobName) {
        try {
            TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_GROUP_NAME);
            sched.pauseTrigger(triggerKey);// 停止触发器
            sched.unscheduleJob(triggerKey);// 移除触发器
            JobKey jobKey = new JobKey(jobName, TRIGGER_GROUP_NAME);
            sched.deleteJob(jobKey);// 删除任务
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description: 移除一个任务
     *
     * @param sched
     *            调度器
     * @param jobName
     * @param jobGroupName
     * @param triggerName
     * @param triggerGroupName
     *
     * @Title: QuartzManager.java
     */
    public static void removeJob(Scheduler sched, String jobName, String jobGroupName, String triggerName, String triggerGroupName) {
        try {
            TriggerKey triggerKey = new TriggerKey(triggerName, triggerGroupName);
            sched.pauseTrigger(triggerKey);// 停止触发器
            sched.unscheduleJob(triggerKey);// 移除触发器
            JobKey jobKey = new JobKey(jobName, jobGroupName);
            sched.deleteJob(jobKey);// 删除任务
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description:启动所有定时任务
     *
     * @param sched
     *            调度器
     *
     * @Title: QuartzManager.java
     */
    public static void startJobs(Scheduler sched) {
        try {
            sched.start();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @Description:关闭所有定时任务
     *
     *
     * @param sched
     *            调度器
     *
     *
     * @Title: QuartzManager.java
     */
    public static void shutdownJobs(Scheduler sched) {
        try {
            if (!sched.isShutdown()) {
                sched.shutdown();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * * @Description:执行一次任务
     *
     *
     * @param sched
     * @param jobName
     * @param jobGroupName
     *
     *
     * @Title: QuartzManager.java
     */
    public static void triggerJob(Scheduler sched, String jobName, String jobGroupName) {
    	try {
    	    JobKey jobKey= new JobKey(jobName, jobGroupName);
    		sched.triggerJob(jobKey);
    		log.info(jobName + "执行一次");
    	} catch (Exception e) {
    		throw new RuntimeException(e);
    	}
    }

    /**
     * * @Description:任务无效，暂停任务
     *
     *
     * @param sched
     * @param jobName
     * @param jobGroupName
     *
     *
     * @Title: QuartzManager.java
     */
    public static void pauseJob(Scheduler sched, String jobName, String jobGroupName) {
    	try {
    	    JobKey jobKey= new JobKey(jobName, jobGroupName);
    		sched.pauseJob(jobKey);
    		log.info(jobName + "暂停、无效");
    	} catch (Exception e) {
    		throw new RuntimeException(e);
    	}
    }

    /**
     * * @Description:任务有效，重新启动任务
     *
     *
     * @param sched
     * @param jobName
     * @param jobGroupName
     *
     *
     * @Title: QuartzManager.java
     */
    public static void resumeJob(Scheduler sched, String jobName, String jobGroupName) {
    	try {
    	    JobKey jobKey= new JobKey(jobName, jobGroupName);
    		sched.resumeJob(jobKey);
    		log.info(jobName + "重启、有效");
    	} catch (Exception e) {
    		throw new RuntimeException(e);
    	}
    }

    /**
     * * @Description:触发器状态
     *
     *
     * @param sched
     * @param triggerName
     * @param triggerGroupName
     *
     *
     * @Title: QuartzManager.java
     */
    public static int getTriggerState(Scheduler sched, String triggerName, String triggerGroupName) {
    	int state;
    	try {
    	    TriggerKey triggerKey = new TriggerKey(triggerName, triggerGroupName);
    		state = sched.getTriggerState(triggerKey).ordinal();
    		log.info(triggerName + "状态");
    	} catch (Exception e) {
    		throw new RuntimeException(e);
    	}
    	return state;
    }
}